from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.core.paginator import Paginator
from django.utils.timezone import utc

from common.models import Hosts
from datetime import datetime
import time,json,os
import paramiko

# Create your views here.
def path_exists(host, user, path):
    '''判断主机上的目录或文件是否存在'''
    import pipes, subprocess  

    ssh_host = '%s@%s'%(user, host)  
    res = subprocess.call( ['ssh', ssh_host, 'test -e ' + pipes.quote(path)] )  

    if (res == 0):  
        return True
    else:  
        return False

def ssh_connect(host, user, passwd=''):
    '''通过SSH远程连接主机'''
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        if passwd:
            ssh.connect(hostname=host, username=user, password=passwd)
        else:
            ssh.connect(hostname=host, username=user)
    except Exception as err:
        print(err)
        return None

    return ssh

def ssh_install(ssh, host, user):
    '''通过SSH在远程主机上安装和运行自动监控程序'''
    def_path = '/home/ubuntu/python/'
    monitor_file = 'automonitor.py'

    try:
        # 新建程序执行目录
        if not path_exists(host, user, def_path):
            cmd = 'mkdir -p ' + def_path
            stdin, stdout, stderr = ssh.exec_command(cmd)
            if len(stderr.readlines()):
                print('新建程序执行目录失败！')
                return False

        # 如果存在同名程序文件先删除
        if path_exists(host, user, def_path + monitor_file):
            cmd = 'rm -f %s'%(def_path + monitor_file)
            stdin, stdout, stderr = ssh.exec_command(cmd)
            if len(stderr.readlines()):
                print('删除同名程序文件失败！')
                return False

        # 拷贝程序文件
        cmd = 'scp ./%s %s@%s:%s'%(monitor_file, user, host, def_path)
        if os.system(cmd) != 0:
            print('拷贝程序文件失败！')
            return False

        # 安装依赖软件
        cmd = 'sudo apt update && sudo apt install python3 && sudo apt install -y python3-pip && sudo pip3 install psutil && sudo pip3 install pymysql'
        stdin, stdout, stderr = ssh.exec_command(cmd)

        # 运行自动监控程序
        cmd='python3 %s%s &'%(def_path, monitor_file)
        stdin, stdout, stderr = ssh.exec_command(cmd)
    except Exception as err:
        print(err)
        return False

    return True

def index(request, pIndex):
    '''浏览主机监控清单信息'''
    #获取主机监控清单信息
    #hlist = Hosts.objects.all()

    #获取主机监控清单查询对象
    mod = Hosts.objects
    mywhere=[]          #定义一个用于存放搜索条件列表

    # 获取、判断并封装关键字keyword搜索
    kw = request.GET.get("keyword",None)
    if kw:
        # 查询商品名中只要含有关键字的都可以
        list = mod.filter(Q(tag__contains=kw) | Q(ip__contains=kw))
        mywhere.append("keyword="+kw)
    else:
        list = mod.filter()

    #执行分页处理
    pIndex = int(pIndex)
    page = Paginator(list,5)  #以5条每页创建分页对象
    maxpages = page.num_pages #最大页数
    #判断页数是否越界
    if pIndex > maxpages:
        pIndex = maxpages
    if pIndex < 1:
        pIndex = 1
    list2 = page.page(pIndex) #当前页数据
    plist = page.page_range   #页码数列表

    #封装信息加载模板输出
    context = {"hostslist":list2,'plist':plist,'pIndex':pIndex,'maxpages':maxpages,'mywhere':mywhere}
    return render(request,"myadmin/hosts/index.html",context)

def add(request):
    '''加载添加主机信息页面'''
    context = {}
    return render(request,"myadmin/hosts/add.html",context)

def insert(request):
    '''执行添加主机信息'''
    #通过SSH远程登录主机
    host_ip = request.POST['ip']
    user = request.POST['user']
    passwd = request.POST['passwd']
    ssh = ssh_connect(host_ip, user, passwd)
    if ssh is None:
        context={"info":"主机远程登录失败，主机信息没有保存！"}
        return render(request,"myadmin/info.html",context)

    #保存主机信息
    try:
        item = Hosts()
        item.tag = request.POST['tag']
        item.ip = host_ip
        item.state = 1
        item.addtime = datetime.utcnow().replace(tzinfo=utc).strftime("%Y-%m-%d %H:%M:%S")
        item.save()
    except Exception as err:
        print(err)
        context={"info":"主机远程登录成功但主机信息添加失败，请重新添加！"}
        return render(request,"myadmin/info.html",context)

    if not ssh_install(ssh, host_ip, user):
        context={"info":"主机远程登录成功且主机信息添加成功，但远程安装和运行自动监控程序失败，请检查后重新添加！"}
        return render(request,"myadmin/info.html",context)

    context = {"info":"恭喜你，主机远程登录，主机信息添加，远程安装和运行自动监控程序均成功，可以开始监控主机运行状态！"}
    return render(request,"myadmin/info.html",context)

def delete(request,hid):
    '''删除主机信息'''
    try:
        item = Hosts.objects.get(id=hid)
        item.delete()
        context={"info":"删除成功！"}
    except Exception as err:
        print(err)
        context={"info":"删除失败！"}
    return render(request,"myadmin/info.html",context)


def edit(request,hid):
    '''加载编辑主机信息页面'''
    try:
        #获取主机信息对象
        item = Hosts.objects.get(id=hid)
        context={"host":item}
        return render(request,"myadmin/hosts/edit.html",context)
    except Exception as err:
        print(err)
        context={"info":"没有找到要修改的信息！"}
        return render(request,"myadmin/info.html",context)

def update(request,hid):
    '''执行编辑主机信息'''
    #获取主机信息对象
    item = Hosts.objects.get(id=hid)
    old_ip = item.ip
    new_ip = request.POST['ip']
    user = request.POST['user']
    passwd = request.POST['passwd']

    #如果ip改动，需要重新远程连接主机
    if new_ip != old_ip:
        ssh = ssh_connect(new_ip, user, passwd)
        if ssh is None:
            context={"info":"主机远程登录失败，主机信息没有保存！"}
            return render(request,"myadmin/info.html",context)

    #保存主机信息
    try:
        item.tag = request.POST['tag']
        item.ip = new_ip
        item.save()
    except Exception as err:
        print(err)
        if new_ip != old_ip:
            context={"info":"新的IP主机远程登录成功但主机信息修改失败，请重新修改！"}
        else:
            context={"info":"主机信息修改失败！"}
        return render(request,"myadmin/info.html",context)

    if new_ip != old_ip:
        if not ssh_install(ssh, new_ip, user):
            context={"info":"新的IP主机远程登录成功且主机信息添加成功，但远程安装和运行自动监控程序失败，请检查后重新添加！"}
        else:
            context = {"info":"恭喜你，主机远程登录，主机信息添加，远程安装和运行自动监控程序均成功，可以开始监控主机运行状态！"}
    else:
        context={"info":"主机信息修改成功！"}

    return render(request,"myadmin/info.html",context)
